home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Demo / www / wwwserver.py < prev    next >
Text File  |  1996-03-12  |  3KB  |  139 lines

  1. #! /usr/local/bin/python
  2.  
  3. # Absolutely minimal WWW server
  4. # Usage: wwwserver [directory [port]]
  5. # Default directory is '.', default port is 2784.
  6. # Logging of connections and requests is done to stdout
  7. # Unexpected server crashes may write their stack trace etc. to stderr
  8.  
  9. import sys
  10. import time
  11. import os
  12. import string
  13. import getopt
  14. import socket
  15. import time
  16. import calendar
  17. import wwwlib
  18.  
  19. DEF_PORT = 2784
  20. DEF_DIR = '.'
  21.  
  22. thishost = socket.gethostname()
  23. thisport = None
  24. thisdir = None
  25.  
  26. def main():
  27.     global thisport, thisdir
  28.     log('started')
  29.     opts, args = getopt.getopt(sys.argv[1:], '')
  30.     if len(args) > 2:
  31.         print 'usage: wwwserver [port [directory]]'
  32.         sys.exit(2)
  33.     #
  34.     if len(args) > 0:
  35.         thisdir = args[0]
  36.     else:
  37.         thisdir = DEF_DIR
  38.     if thisdir[-1:] <> '/':
  39.         thisdir = thisdir + '/'
  40.     if not os.path.isdir(thisdir):
  41.         print thisdir, ': not a directory'
  42.         sys.exit(2)
  43.     #
  44.     if len(args) > 1:
  45.         thisport = string.atoi(args[1])
  46.     else:
  47.         thisport = DEF_PORT
  48.     #
  49.     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  50.     s.bind('', thisport)
  51.     s.listen(0)
  52.     sys.exitfunc = lastwish
  53.     #
  54.     log('ready for requests on port', thisport, 'for directory', thisdir)
  55.     #
  56.     while 1:
  57.         log('waiting for next request')
  58.         conn, (client, port) = s.accept()
  59.         serve(conn, client)
  60.         log('closing connection to', client)
  61.         conn.close()
  62.         del conn
  63.  
  64.  
  65. def serve(s, client):
  66.     log('connection from', client)
  67.     request = s.recv(1024)
  68.     key = request[:4]
  69.     if string.lower(key) <> 'get ':
  70.         log('bad request from', client, `request`[:40])
  71.         return
  72.     if request[-1:] == '\n': request = request[:-1]
  73.     if request[-1:] == '\r': request = request[:-1]
  74.     addr = string.strip(request[4:])
  75.     scheme, host, port, path, search, anchor = wwwlib.parse_addr(addr)
  76.     if scheme and scheme <> 'http':
  77.         log('request bad scheme from', client, 'in', `addr`)
  78.         s.send('Bad scheme in requested address\n')
  79.         return
  80.     if host and host <> thishost:
  81.         log('request bad host from', client, 'in', `addr`)
  82.         s.send('Non-local host in requested address\n')
  83.         return
  84.     if port and port <> `thisport`:
  85.         log('request bad port from', client, 'in', `addr`)
  86.         s.send('Unexpected host in requested address\n')
  87.         return
  88.     if search:
  89.         log('request with search key from', client, 'in', `addr`)
  90.         s.send('Search key not supported by this server\n')
  91.         return
  92.     while path[:1] == '/': path = path[1:]
  93.     path = os.path.normpath(path)
  94.     if path[:1] == '.':
  95.         log('request illegal path from', client, 'in', `addr`)
  96.         s.send('Illegal path in requested address\n')
  97.         return
  98.     path = thisdir + path
  99.     if not os.path.isfile(path):
  100.         log('request non-file path from', client, 'in', `addr`)
  101.         s.send('Invalid path in requested address\n')
  102.         return
  103.     try:
  104.         f = open(path, 'r')
  105.     except IOError, msg:
  106.         log('IOError', msg, 'opening', path, 'for', client)
  107.         s.send('Access violation in requested address\n')
  108.         return
  109.     log('sending', path[len(thisdir):], 'to', client)
  110.     sf = s.makefile('w')
  111.     if path[-5:] != '.html':
  112.         log('sending <PLAINTEXT> prefix to', client)
  113.         sf.write('<PLAINTEXT>\n')
  114.     try:
  115.         while 1:
  116.             buf = f.read(8192)
  117.             if not buf: break
  118.             sf.write(buf)
  119.     except IOError, msg:
  120.         log('IOError', msg, 'reading', path, 'for', client)
  121.     f.close()
  122.     sf.close()
  123.  
  124.  
  125. def lastwish():
  126.     log('killed')
  127.  
  128.  
  129. def log(*args):
  130.     now = time.time()
  131.     broken_up_time = time.localtime(now)[:-1] # Strip trailing what?
  132.     print calendar.asctime(broken_up_time)[4:],
  133.     for arg in args: print arg,
  134.     print
  135.     sys.stdout.flush()
  136.  
  137.  
  138. main()
  139.